"""
租户配置服务
用于获取当前租户的配置信息，替代原来的环境变量
"""
from flask import g, current_app
from app.models.tenant_config import TenantConfig, TenantConfigService, ConfigTypes
import os


class DynamicTenantConfig:
    """动态租户配置类"""

    def __init__(self):
        self._cache = {}

    def get_current_tenant_id(self):
        """获取当前租户ID"""
        from flask import has_request_context
        if has_request_context():
            return getattr(g, 'tenant_id', 1)  # 默认租户ID为1
        else:
            return 1  # 在没有请求上下文时使用默认租户

    def get_config(self, config_type, config_key, default_value=None):
        """获取当前租户的配置"""
        tenant_id = self.get_current_tenant_id()
        cache_key = f"{tenant_id}:{config_type}:{config_key}"

        # 先从缓存获取
        if cache_key in self._cache:
            return self._cache[cache_key]

        # 从数据库获取
        value = TenantConfigService.get_config(tenant_id, config_type, config_key, default_value)

        # 如果数据库没有，尝试从环境变量获取（兼容性）
        if value is None:
            env_key = f"{config_type.upper()}_{config_key.upper()}"
            value = os.getenv(env_key, default_value)

        # 缓存结果
        self._cache[cache_key] = value
        return value

    def clear_cache(self, tenant_id=None):
        """清除缓存"""
        if tenant_id:
            # 清除指定租户的缓存
            keys_to_remove = [k for k in self._cache.keys() if k.startswith(f"{tenant_id}:")]
            for key in keys_to_remove:
                del self._cache[key]
        else:
            # 清除所有缓存
            self._cache.clear()

    # 微信小程序配置
    @property
    def wechat_mp_app_id(self):
        return self.get_config(ConfigTypes.WECHAT_MP, 'app_id')

    @property
    def wechat_mp_app_secret(self):
        return self.get_config(ConfigTypes.WECHAT_MP, 'app_secret')

    # 微信支付配置
    @property
    def wechat_pay_mch_id(self):
        return self.get_config(ConfigTypes.WECHAT_PAY, 'mch_id')

    @property
    def wechat_pay_api_key(self):
        return self.get_config(ConfigTypes.WECHAT_PAY, 'api_key')

    @property
    def wechat_pay_cert_path(self):
        return self.get_config(ConfigTypes.WECHAT_PAY, 'cert_path')

    @property
    def wechat_pay_key_path(self):
        return self.get_config(ConfigTypes.WECHAT_PAY, 'key_path')

    # 微信公众号配置
    @property
    def wechat_gzh_app_id(self):
        return self.get_config(ConfigTypes.WECHAT_GZH, 'app_id')

    @property
    def wechat_gzh_app_secret(self):
        return self.get_config(ConfigTypes.WECHAT_GZH, 'app_secret')

    @property
    def wechat_gzh_token(self):
        return self.get_config(ConfigTypes.WECHAT_GZH, 'token')

    @property
    def wechat_gzh_encoding_aes_key(self):
        return self.get_config(ConfigTypes.WECHAT_GZH, 'encoding_aes_key')

    # 豆包AI配置
    @property
    def doubao_ai_api_key(self):
        return self.get_config(ConfigTypes.DOUBAO_AI, 'api_key')

    @property
    def doubao_ai_base_url(self):
        return self.get_config(ConfigTypes.DOUBAO_AI, 'base_url')

    @property
    def doubao_ai_model(self):
        return self.get_config(ConfigTypes.DOUBAO_AI, 'model')

    @property
    def tcos_secret_id(self):
        return self.get_config(ConfigTypes.TCOS, 'secret_id')

    @property
    def tcos_secret_key(self):
        return self.get_config(ConfigTypes.TCOS, 'secret_key')

    @property
    def tcos_region(self):
        return self.get_config(ConfigTypes.TCOS, 'region')

    @property
    def tcos_bucket(self):
        return self.get_config(ConfigTypes.TCOS, 'bucket')

    def get_wechat_mp_config(self):
        """获取微信小程序完整配置"""
        return {
            'app_id': self.wechat_mp_app_id,
            'app_secret': self.wechat_mp_app_secret
        }

    def get_wechat_pay_config(self):
        """获取微信支付完整配置"""
        return {
            'mch_id': self.wechat_pay_mch_id,
            'api_key': self.wechat_pay_api_key,
            'cert_path': self.wechat_pay_cert_path,
            'key_path': self.wechat_pay_key_path,
            'app_id': self.wechat_mp_app_id,
        }

    def get_wechat_gzh_config(self):
        """获取微信公众号完整配置"""
        return {
            'app_id': self.wechat_gzh_app_id,
            'app_secret': self.wechat_gzh_app_secret,
            'token': self.wechat_gzh_token,
            'encoding_aes_key': self.wechat_gzh_encoding_aes_key,
            'mch_id': self.wechat_pay_mch_id,
            'api_key': self.wechat_pay_api_key,
        }

    def get_doubao_ai_config(self):
        """获取豆包AI完整配置"""
        return {
            'api_key': self.doubao_ai_api_key,
            'base_url': self.doubao_ai_base_url,
            'model': self.doubao_ai_model
        }

    def get_tcos_config(self):
        """获取腾讯云COS完整配置"""
        return {
            'secret_id': self.tcos_secret_id,
            'secret_key': self.tcos_secret_key,
            'region': self.tcos_region,
            'bucket': self.tcos_bucket
        }


# 全局配置实例
tenant_config = DynamicTenantConfig()


def get_tenant_config():
    """获取租户配置实例"""
    return tenant_config


def init_default_tenant_configs():
    """初始化默认租户配置"""
    from app.models.tenant_config import TenantConfigService, ConfigTypes
    from flask import current_app

    # 默认租户ID
    default_tenant_id = 1

    # 从环境变量迁移到数据库（仅在配置不存在时）
    env_configs = {
        ConfigTypes.WECHAT_MP: {
            'app_id': os.getenv('MINIPROGRAM_APPID'),  # 修正环境变量名
            'app_secret': os.getenv('MINIPROGRAM_SECRET')  # 修正环境变量名
        },
        ConfigTypes.WECHAT_PAY: {
            'mch_id': os.getenv('MCH_ID'),  # 修正环境变量名
            'api_key': os.getenv('PAY_KEY'),  # 修正环境变量名
            'cert_path': os.getenv('CERT_PATH'),
            'key_path': os.getenv('KEY_PATH')
        },
        ConfigTypes.WECHAT_GZH: {
            'app_id': os.getenv('GMINIPROGRAM_APPID'),  # 修正环境变量名
            'app_secret': os.getenv('GMINIPROGRAM_SECRET'),  # 修正环境变量名
            'token': os.getenv('WECHAT_TOKEN'),  # 修正环境变量名
            'encoding_aes_key': os.getenv('WECHAT_ENCODING_AES_KEY')
        },
        ConfigTypes.DOUBAO_AI: {
            'api_key': os.getenv('DOUBAO_AI_API_KEY'),
            'base_url': os.getenv('DOUBAO_AI_BASE_URL'),
            'model': os.getenv('DOUBAO_AI_MODEL')
        },
        ConfigTypes.TCOS: {
            'secret_id': os.getenv('TCOS_SECRET_ID'),
            'secret_key': os.getenv('TCOS_SECRET_KEY'),
            'region': os.getenv('TCOS_REGION'),
            'bucket': os.getenv('TCOS_BUCKET')
        }
    }

    try:
        for config_type, configs in env_configs.items():
            for config_key, config_value in configs.items():
                if config_value:  # 只迁移有值的配置
                    try:
                        # 检查是否已存在
                        existing = TenantConfigService.get_config(default_tenant_id, config_type, config_key)
                        if existing is None:
                            TenantConfigService.set_config(
                                default_tenant_id,
                                config_type,
                                config_key,
                                config_value,
                                f"从环境变量迁移的{config_type}配置"
                            )
                            current_app.logger.info(f"已迁移配置: {config_type}.{config_key}")
                    except Exception as e:
                        current_app.logger.warning(f"迁移配置失败 {config_type}.{config_key}: {str(e)}")
    except Exception as e:
        current_app.logger.error(f"初始化租户配置失败: {str(e)}")
        # 不抛出异常，允许应用继续启动


# 装饰器：确保有租户配置
def require_tenant_config(config_type, *required_keys):
    """装饰器：确保租户有必要的配置"""

    def decorator(func):
        def wrapper(*args, **kwargs):
            tenant_id = getattr(g, 'tenant_id', 1)

            # 检查必要配置是否存在
            missing_configs = []
            for key in required_keys:
                value = TenantConfigService.get_config(tenant_id, config_type, key)
                if not value:
                    missing_configs.append(key)

            if missing_configs:
                from flask import jsonify
                return jsonify({
                    'code': 1,
                    'message': f'租户缺少必要配置: {config_type}.{", ".join(missing_configs)}',
                    'missing_configs': missing_configs
                }), 400

            return func(*args, **kwargs)

        return wrapper

    return decorator
